﻿using Dapper;
using Microsoft.AspNetCore.Components.Forms;
using System.Data.SqlClient;

namespace Dapper333
{
    public class 结果
    {
        public 结果() {

            // 结果

            /* 1、结果为匿名类型：
             * 
                    可以使用扩展方法执行查询并使用动态类型映射结果。

                    匿名类型结果可以从以下扩展方法映射：
                        
                            1、Query
                            2、QueryFirst
                            3、QueryFirstOrDefault
                            4、QuerySingle
                            5、QuerySingleOrDefault
                    这些扩展方法可以从IDbConnection类型的任意对象中调用。
             */




            // eg: query方法可以执行查询并将结果映射到动态类型列表
            string sql = "Select * from Invoice";

                            using (var connection = new SqlConnection())
                            {
                                connection.Open();
                                var invoices = connection.Query(sql).ToList();
                            }

                    // eg： QueryFirst方法可以执行查询并将第一个结果映射到动态类型列表
                            string sql2 = "Select * from Invoice Where InvoiceID = @InvocieID";

                            using (var connection = new SqlConnection())
                            {
                                connection.Open();
                                var invoice = connection.QueryFirst(sql2, new { InvocieID = 1});
                            }

                    // eg: QueryFirstOrDefault 方法可以执行查询并将第一个结果映射到强类型列表，如果序列不包含任何元素则为默认值。
                            string sql3 = "Select * from OrderDetails WHERE OrderDetailID = @OrderDetailID";

                            using (var connection = new SqlConnection())
                            {
                                var orderDetail = connection.QueryFirstOrDefault(sql, new { OrderDetailID = 1 });
                            }

                    // eg:QuerySingle方法可以执行查询并将第一个结果映射到动态类型列表，如果序列中没有元素则会引发异常。
                            string sql4 = "Select * form Invoice Where InvoiceID =@InvoiceID;";

                            using (var connection = new SqlConnection())
                            {
                                connection.Open();

                                var invoice = connection.QuerySingle(sql4, new { InvoiceID = 1 });
                            }

                    // eg:QuerySingelOrDefault 方法可以执行查询并将第一个结果映射到动态类型列表，如果序列为空则为默认值；如果序列中有多个元素，则此方法引发异常。
                            string sql5 = "Select * from  Invoice Where InvoiceID = @InvoiceID";

                            using (var connection = new SqlConnection())
                            {
                                connection.Open();

                                var inovoice = connection.QuerySingleOrDefault(sql5, new { InvoiceID = 1 });
                            }


            // 2、结果强类型：
            /*
                    可以使用扩展方法执行查询并使用动态类型映射结果。

                    强类型结果可以从以下扩展方法映射：

                       ①、Query
                       ②、QueryFirst
                       ③、QueryFirstOrDefault
                       ④、QuerySingle
                       ⑤、QuerySingleOrDefault
             */

                    // eg: Query可以执行查询并将结果映射到强类型列表
                        string sql7 = "Select top(10) from Orderdetails";
                        using (var connection = new SqlConnection())
                        {
                            var orderDetails = connection.Query<OrderDetail>(sql).ToList();
                        }

                    // eg:QueryFirst方法可以执行查询并将第一个结果映射到强类型列表
                        string sql8 = "Select * from OrderDetails where OrderDetailID= @OrderDetailID;";

                        using (var connection = new SqlConnection())
                        {
                            var orderDetail = connection.QueryFirst<OrderDetail>(sql, new { OrderDetail = 1 });
                        }

                    // eg: QueryFirstOrDefault 方法可以执行查询并将第一个结果映射到强类型列表，如果序列不包含任何元素，则为默认值。
                        string sql9 = "Select * from OrderDetails where OrderDetailID = @OrderDetatail";

                        using (var connection = new SqlConnection())
                        {
                            var orderDetail = connection.QueryFirstOrDefault<OrderDetail>(sql9, new { OrderDetail = 1 });
                        }

                    // eg: QuerySingle 方法可以执行查询并将第一个结果映射到强类型列表，如果序列中没有元素会引发异常。
                        string sql10 = "select * from OrderDetail where OrderDetailID = @OrderDetailID";

                        using (var connection = new SqlConnection())
                        {
                            var orderDetail = connection.QuerySingle<OrderDetail>(sql10, new { OrderDertailID = 1 });
                        }

                    // eg: QuerySingleOrDefault 方法可以执行查询并将第一个结果映射到强类型列表，如果序列为空则为默认值，如果序列中有多个元素，则此方法将引发异常。
                        string sql11 = "select * from OrderDetail where OrderDetailID =@OrderDetailID";

                        using (var connection = new SqlConnection())
                        {
                            var orderDetail = connection.QuerySingleOrDefault<OrderDetail>(sql11, new { OrderDetailID = 1 });
                        }

            // 3、结果多映射
            /*
                描述：
                        可以使用扩展方法执行查询并将结果映射到具有关系的强类型列表。

                        关系可以是：
                                    ①、一对一 
                                    ②、一对多
                        (这些方法可以从IDBConnection类型的任意对象中调用)
            */


                // eg:  查询结果多映射   (一对一)  Query方法可以执行查询并将经过映射到具有一对一关系的强类型列表：
                        string sql12 = "select * from Invoice As A Inner Join B on a.InvoiceID = B.InvoiceID;";

                        using (var connection = new SqlConnection())
                        {
                            connection.Open();

                            var invoices = connection.Query<Invoice, InvoiceDetail, Invoice>(sql,
                                                                                           (invoice, invoiceDetail) =>
                                                                                           {
                                                                                               invoice.InvoiceDetail = invoiceDetail;
                                                                                               return invoice;
                                                                                           },
                                                                                           splitOn: "InvoiceID")
                                                                                           .Distinct().ToList();
                        }

                // eg: 查询结果映射(一对多)  query方法可以执行查询并将结果映射到一对多的强类型列表中。
                        string sql13 = "Select * from Invoice as A Inner Join InvoceItem As B On A.InvoceID = B.InvoiceID ";

                        using (var connection = new SqlConnection())
                        {
                            connection.Open();

                            var invoiceDictionary = new Dictionary<int, Invoice>();

                            var invoice = connection.Query<Invoice, InvoiceItem, Invoice>(sql,
                                                                                            (invoice, invoiceItem) =>
                                                                                            {
                                                                                                Invoice invoiceEntity;
                                                                                                if (!invoiceDictionary.TryGetValue(invoice.InvoiceID, out invoiceEntity))
                                                                                                {
                                                                                                    invoiceEntity = invoice;
                                                                                                    invoiceEntity.InvoiceItems = new List<InvoiceItem>();
                                                                                                    invoiceDictionary.Add(invoice.InvoiceID, invoiceEntity);
                                                                                                }
                                                                                                invoiceEntity.InvoiceItems.Add(invoiceItem);
                                                                                                return invoiceEntity;
                                                                                            },
                                                                                            splitOn:"InvoiceID")
                                                                                            .Distinct()
                                                                                            .ToList();
                        }
        }
    }
}
